package com.chenl.provider.DEMOS.Spring.扫描候选组件;

import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

public class ScanController {

    //--------------------------------------------扫描类----------------------------------------------------
    /**
     * ClassPathScanningCandidateComponentProvider 可以通过指定包名或者类路径来进行扫描，并支持添加多个过滤器来筛选所需的组件。
     * 常见的过滤器类型有基于注解的过滤器（例如 AnnotationTypeFilter）和基于类型的过滤器（例如 AssignableTypeFilter）等
     * @param packageName
     * @return
     */
    public static Set<Class<?>> scanClazz(String packageName,Class annoClass) {
        Set<Class<?>> feignInterfaces = new HashSet<>();
        // 创建类路径扫描提供者
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        //添加过滤器，如AnnotationTypeFilter就是过滤带有@Component注解的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(annoClass));
        // 扫描指定包下的所有类
        for (org.springframework.beans.factory.config.BeanDefinition beanDef : scanner.findCandidateComponents(packageName)) {
            try {
                // 获取类的实例
                Class<?> clazz = Class.forName(beanDef.getBeanClassName());
                feignInterfaces.add(clazz);
            } catch (ClassNotFoundException e) {
                // 处理异常
            }
        }
        return feignInterfaces;
    }

    public static Object invokeMethod(Object clazz, String methodName) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        Object result =null;
        try {
            // 获取方法对象
            Method method = clazz.getClass().getMethod(methodName);
            // 调用方法
            result = method.invoke(clazz);
            return result;
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
            throw e;
        }
    }
}
